﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Transactions;
using Caixa.BLL;
using Caixa.Model;
using Caixa.Model.Interface;
using Caixa.Model.Enum;
using Caixa.ServiceBinder;

namespace Caixa
{
	public partial class Frm_DOC : Caixa.Frm_Base
	{
		#region " Constructor "

		public Frm_DOC()
		{
			InitializeComponent();
		}

		#endregion

		#region " Events "

		private void rdbDOCTipoFavorecidoFisica_CheckedChanged(object sender, EventArgs e)
		{
			lblDOC_CPFCNPJ.Text = "CPF";
			txtDOC_CPFCNPJ.Mask = "999,999,999-99";
		}

		private void rdbDOCTipoFavorecidoJuridica_CheckedChanged(object sender, EventArgs e)
		{
			lblDOC_CPFCNPJ.Text = "CNPJ";
			txtDOC_CPFCNPJ.Mask = "99,999,999/9999-99";
		}

		private void btnConfirmar_Click(object sender, EventArgs e)
		{
			if (!ValidaPreenchimentoCampos())
				return;

			this.Hide();

			bool sucess = false;

			Frm_Processando frm_Processando = new Frm_Processando();
			frm_Processando.Show();
			frm_Processando.Refresh();
			System.Threading.Thread.Sleep(500);

			// Chama o processamento de efetuar o DOC
			sucess = EfetuarDOC();

			if (sucess)
			{
				frm_Processando.Mensagem = "DOC realizado com sucesso!";
				frm_Processando.Visible = false;
				frm_Processando.KeyPreview = true;
				frm_Processando.ShowDialog();
			}
			else
			{
				frm_Processando.Dispose();
				this.Show();
			}
		}

		private void btnCancelar_Click(object sender, EventArgs e)
		{
			this.Close();
		}

		#endregion

		#region " Methods "

		#region " DOC "

		private bool EfetuarDOC()
		{
			bool success = false;
			Transacao transacao;

			try
			{
				IDestinatarioTransacao destinatarioTransacao;
				double valor;

				using (TransactionScope ts = new TransactionScope())
				{
					// Cadastra o Favorecido
					if (rdbDOCTipoFavorecidoFisica.Checked)
						destinatarioTransacao = CadastraFavorecidoPessoaFisica();
					else
						destinatarioTransacao = CadastraFavorecidoPessoaJuridica();

					// Inclui a transação do DOC
					double.TryParse(txtDOC_Valor.Text, out valor);
					transacao = ContaBLL.EfetuaDOC(CaixaEletronicoBLL.ContaLogada, destinatarioTransacao, DateTime.Now, valor);

					ts.Complete();
				}

				try
				{
					// Envia a transação do DOC para o binder que enviará para o respectivo banco
					using (ServiceBinderSoapClient serviceBinder = new ServiceBinderSoapClient())
					{
						int numeroBancoRemetente = BancoBLL.GetByID(CaixaEletronicoBLL.ContaLogada.IDAgencia).Numero;
						int numeroAgenciaRemetente = AgenciaBLL.GetByID(CaixaEletronicoBLL.ContaLogada.IDAgencia).Numero;
						int numeroContaRemetente = CaixaEletronicoBLL.ContaLogada.Numero;

						int numeroBancoDestinatario = BancoBLL.GetByID(destinatarioTransacao.IDBanco).Numero;
						int numeroAgenciaDestinatario = destinatarioTransacao.NumeroAgencia;
						int numeroContaDestinatario = destinatarioTransacao.NumeroConta;

						// Realiza o envio do DOC pelo Binder (WebService)
						success = serviceBinder.ProcessaDOC(transacao.ID, numeroBancoRemetente, numeroAgenciaRemetente, numeroContaRemetente, numeroBancoDestinatario, numeroAgenciaDestinatario, numeroContaDestinatario, valor);
					}
				}
				catch (Exception e)
				{
					throw e;
				}
				finally
				{
					// Faz o estorno do DOC na conta que enviou se o Binder recusar a transação
					if (!success && (transacao != null))
					{
						using (TransactionScope ts = new TransactionScope())
						{
							if (!ContaBLL.DevolveDOC(transacao.ID))
								throw new Exception(string.Format("Ocorreu um erro ao efetuar o estorno do DOC Nº {0}. Entre em contato com o banco.", transacao.ID));
							ts.Complete();
						}
						throw new Exception(string.Format("O DOC Nº {0} foi recusado em seu destino, foi realizado um estorno em sua conta.", transacao.ID));
					}
				}
			}
			catch (Exception e)
			{
				MessageBox.Show(e.Message, "Mensagem", MessageBoxButtons.OK, MessageBoxIcon.Warning);
			}

			return success;
		}

		#endregion

		#region " Favorecido "

		private IDestinatarioTransacao CadastraFavorecidoPessoaFisica()
		{
			string cpf = txtDOC_CPFCNPJ.Text.Replace(".", "").Replace("-", "");
			DestinatarioTransacaoPessoaFisica destinatario = DestinatarioTransacaoPessoaFisicaBLL.GetByCPF(cpf);
			bool exists = (destinatario != null);

			if (!exists)
				destinatario = new DestinatarioTransacaoPessoaFisica();

			destinatario.CPF = cpf;

			destinatario.Nome = txtDOC_NomeFavorecido.Text;

			int numeroBanco;
			int.TryParse(txtDOC_Banco.Text, out numeroBanco);
			Banco banco = BancoBLL.GetByNumero(numeroBanco);
			if (banco == null)
				throw new Exception("Banco de destino inválido!");
			destinatario.IDBanco = banco.ID;

			int numeroAgencia;
			int.TryParse(txtDOC_Agencia.Text, out numeroAgencia);
			destinatario.NumeroAgencia = numeroAgencia;

			int numeroConta;
			int.TryParse(txtDOC_Conta.Text, out numeroConta);
			destinatario.NumeroConta = numeroConta;

			if (!exists)
				destinatario.ID = DestinatarioTransacaoPessoaFisicaBLL.Insert(destinatario);
			else
				DestinatarioTransacaoPessoaFisicaBLL.Update(destinatario);

			return destinatario;
		}

		private IDestinatarioTransacao CadastraFavorecidoPessoaJuridica()
		{
			string cnpj = txtDOC_CPFCNPJ.Text.Replace(".", "").Replace("/", "").Replace("-", "");
			DestinatarioTransacaoPessoaJuridica destinatario = DestinatarioTransacaoPessoaJuridicaBLL.GetByCNPJ(cnpj);
			bool exists = (destinatario != null);

			if (!exists)
				destinatario = new DestinatarioTransacaoPessoaJuridica();

			destinatario.CNPJ = cnpj;

			destinatario.Nome = txtDOC_NomeFavorecido.Text;

			int numeroBanco;
			int.TryParse(txtDOC_Banco.Text, out numeroBanco);
			Banco banco = BancoBLL.GetByNumero(numeroBanco);
			if (banco == null)
				throw new Exception("Banco de destino inválido!");
			destinatario.IDBanco = banco.ID;

			int numeroAgencia;
			int.TryParse(txtDOC_Agencia.Text, out numeroAgencia);
			destinatario.NumeroAgencia = numeroAgencia;

			int numeroConta;
			int.TryParse(txtDOC_Conta.Text, out numeroConta);
			destinatario.NumeroConta = numeroConta;

			if (!exists)
				destinatario.ID = DestinatarioTransacaoPessoaJuridicaBLL.Insert(destinatario);
			else
				DestinatarioTransacaoPessoaJuridicaBLL.Update(destinatario);

			return destinatario;
		}

		#endregion

		#region " Validação "

		public bool ValidaPreenchimentoCampos()
		{
			bool isValid = false;
			try
			{
				if (string.IsNullOrEmpty(txtDOC_Banco.Text.Trim()))
					throw new Exception("Preencha o banco.");

				if (string.IsNullOrEmpty(txtDOC_Agencia.Text.Trim()))
					throw new Exception("Preencha a agência.");

				if (string.IsNullOrEmpty(txtDOC_Conta.Text.Trim()))
					throw new Exception("Preencha a conta.");

				if (string.IsNullOrEmpty(txtDOC_CPFCNPJ.Text.Replace(".", "").Replace("/", "").Replace("-", "").Trim()))
					throw new Exception("Preencha o CPF/CNPJ.");

				if (string.IsNullOrEmpty(txtDOC_NomeFavorecido.Text.Trim()))
					throw new Exception("Preencha o nome do favorecido.");

				if (string.IsNullOrEmpty(txtDOC_Valor.Text.Trim()))
					throw new Exception("Preencha o valor do DOC.");

				int numeroBanco;
				int.TryParse(txtDOC_Banco.Text, out numeroBanco);
				Banco banco = BancoBLL.GetMySelf();
				if (banco.Numero.Equals(numeroBanco))
					throw new Exception(string.Format("Banco do favorecido [Bco: {0}] não pode ser o mesmo do remetente.", numeroBanco));

				isValid = true;
			}
			catch (Exception e)
			{
				isValid = false;
				MessageBox.Show(e.Message, "Mensagem", MessageBoxButtons.OK, MessageBoxIcon.Warning);
			}

			return isValid;
		}

		#endregion

		#endregion
	}
}
